/**
 * \brief  Implementation of an infinite impulse response filter
 * \author Alexander Nitsch <nitscha@cs.tu-berlin.de>
 *
 * This class implements an infinite impulse response (IIR) filter described by
 * the equation
 *
 *   y(n) = b0*x(n) + b1*x(n-1) + ... + bN*x(n-N)
 *          - a1*y(n-1) - a2*y(n-2) - ... - aM*y(n-M)
 *
 * The current filter output y(n) is composed of a weighted sum of past output
 * samples y(n-1) ... y(n-M) and input samples x(n) ... x(n-N).
 * 
 * Modified by Hristo Hristov (29.11.13)
 */

namespace NOVA
{
    public class IirFilter
    {
        float[] m_pdFirCoeffs;
        float[] m_pdIirCoeffs;
        float[] m_pdInputBuf;
        float[] m_pdOutputBuf;
        int m_uiNumFirCoeffs;
        int m_uiNumIirCoeffs;

        public IirFilter()
        {
            m_uiNumFirCoeffs = 1;
            m_uiNumIirCoeffs = 2;
            m_pdFirCoeffs = new float[1] { 0.12f };
            m_pdInputBuf = new float[1];
            m_pdOutputBuf = new float[2];

            int i;
            for (i = 0; i < 1; i++)
                m_pdInputBuf[i] = 0;

            m_pdIirCoeffs = new float[2] { 1, -(1 - m_pdFirCoeffs[0]) };

            for (i = 0; i < 2; i++)
                m_pdOutputBuf[i] = 0;
        }

        public float Step(float input)
        {
            float sum = 0;

            for (int i = m_uiNumFirCoeffs - 1; i > 0; i--)
            {
                m_pdInputBuf[i] = m_pdInputBuf[i - 1];
                sum += m_pdFirCoeffs[i] * m_pdInputBuf[i];
            }

            m_pdInputBuf[0] = input;
            sum += m_pdFirCoeffs[0] * m_pdInputBuf[0];

            for (int i = m_uiNumIirCoeffs - 1; i > 0; i--)
            {
                m_pdOutputBuf[i] = m_pdOutputBuf[i - 1];
                sum -= m_pdIirCoeffs[i] * m_pdOutputBuf[i];
            }
            m_pdOutputBuf[0] = sum;

            return sum;
        }
    };
}
